package eu.robico.simulator.simulatorinterface.actionpanel;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.JPanel;
import javax.swing.Timer;

import eu.robico.simulator.simulatorinterface.actionpanel.objects.ActionPanelObject;
import eu.robico.simulator.simulatorinterface.actionpanel.objects.UpdateableActionPanelObject;

public class ActionPanel extends JPanel implements ActionListener
{
	private List<ActionPanelObject> objects = new ArrayList<>();
	private List<UpdateableActionPanelObject> updateables = new ArrayList<>();
	private Timer timer = new Timer(3, this);
	
	boolean simulationActive;
	
	public ActionPanel()
	{
		addMouseListener(new ActionPanelMouseListener(this));
		setBackground(Color.BLACK);
		resetActionPanel();
	}
	
	public void resetActionPanel()
	{
		//Reset State
		simulationActive = false;
		
		objects = new ArrayList<>();
		updateables = new ArrayList<>();
		
		//Repaint Action Panel
		repaint();
	}
	
	
	public void loadObstacleSimulation()
	{
		resetActionPanel();
		ActionPanelSimulationFactory.setupObstacleOnColorlaneSimulation(
				this, objects, updateables);
	}
	
	public void loadProgrammedPathSimulation()
	{
		resetActionPanel();
		ActionPanelSimulationFactory.setupProgrammedPathSimulation(
				this, objects, updateables);
	}
	
	public void startSimulation()
	{
		simulationActive = true;
		timer.start();
	}
	
	public void stopSimulation()
	{
		simulationActive = false;
		timer.stop();
	}
	
	public void addObject(ActionPanelObject object)
	{
		objects.add(object);
	}
	
	@Override
	public void paint(Graphics graphics) 
	{
		paintBackground(graphics);
		((Graphics2D) graphics).setRenderingHint(RenderingHints.KEY_ANTIALIASING, // Anti-alias!
		     RenderingHints.VALUE_ANTIALIAS_ON);
		paintObjects((Graphics2D) graphics);
	}

	private void paintBackground(Graphics graphics) 
	{
		super.paint(graphics);
	}
	
	private void paintObjects(Graphics2D graphics)
	{
		for (ActionPanelObject object : objects)
			object.paint(graphics);
	}

	@Override
	public void actionPerformed(ActionEvent e) 
	{
		if (!simulationActive)
			return;
		//Update objects
		for (UpdateableActionPanelObject updateable : updateables)
			updateable.update();
		//Repaint
		repaint();
		//Restart timer
		timer.restart();
	}
	
	public List<ActionPanelObject> getObjects()
	{
		return Collections.unmodifiableList(objects);
	}
}
